/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package eu.easyedu.dictionary.api.util;

import java.sql.Connection;
import java.util.logging.Logger;
import javax.swing.event.EventListenerList;
import org.netbeans.api.db.explorer.ConnectionManager;
import org.netbeans.api.db.explorer.DatabaseConnection;
import org.netbeans.api.db.explorer.DatabaseException;
import org.openide.util.Exceptions;

/**
 *
 * @author hlavki
 */
public class DictionaryConnection implements java.io.Serializable {

    private static final Logger log = Logger.getLogger(DictionaryConnection.class.getName());
    private static final long serialVersionUID = 4268629337109119906L;
    private final DatabaseConnection delegate;
    private transient EventListenerList listenerList;
    private boolean connected;
    private transient ConnectionEvent connectionEvent;

    private enum ConnectionEventType {

        CONNECT, DISCONNECT
    }

    public DictionaryConnection(DatabaseConnection delegate) {
        this.delegate = delegate;
        connected = false;
        listenerList = new EventListenerList();
        connectionEvent = null;
    }

    public Connection getJDBCConnection() {
        if (!connected) {
            connect();
        }
        return delegate.getJDBCConnection();
    }

    public boolean connect() {
        log.info("Thread search " + Thread.currentThread());
        boolean result = false;
        try {
            ConnectionManager.getDefault().showConnectionDialog(delegate);
            Connection conn = delegate.getJDBCConnection();
            result = conn != null && !conn.isClosed();
        } catch (Exception e) {
        }
        if (result) {
            connected = true;
            fireConnectionEvent(ConnectionEventType.CONNECT);
        }
        return result;
    }

    public void disconnect() {
        ConnectionManager.getDefault().disconnect(delegate);
        fireConnectionEvent(ConnectionEventType.DISCONNECT);
        connected = false;
    }

    public boolean isConnected() {
        return connected;
    }

    /**
     * Returns the JDBC driver class that this connection uses.
     *
     * @return the JDBC driver class
     */
    public String getDriverClass() {
        return delegate.getDriverClass();
    }

    /**
     * Returns this connection's database URL.
     *
     * @return the connection's database URL
     */
    public String getDatabaseURL() {
        return delegate.getDatabaseURL();
    }

    /**
     * Returns this connection's default schema.
     *
     * @return the schema
     */
    public String getSchema() {
        return delegate.getSchema();
    }

    /**
     * Returns the user name used to connect to the database.
     *
     * @return the user name
     */
    public String getUser() {
        return delegate.getUser();
    }

    /**
     * Returns the password used to connect to the database.
     *
     * @return the password
     */
    public String getPassword() {
        return delegate.getPassword();
    }

    /**
     * Returns the programmatic name of this connection in the Database Explorer.
     *
     * @return the programmatic name
     */
    public String getName() {
        return delegate.getName();
    }

    /**
     * Returns the name used to display this connection in the UI.
     *
     * @return the display name
     */
    public String getDisplayName() {
        return delegate.getName();
    }

    public void addConnectionEventListener(ConnectionEventListener listener) {
        listenerList.add(ConnectionEventListener.class, listener);
    }

    public void removeConnectionEventListener(ConnectionEventListener listener) {
        listenerList.remove(ConnectionEventListener.class, listener);
    }

    private void fireConnectionEvent(ConnectionEventType type) {
        Object[] listeners = listenerList.getListenerList();
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i] == ConnectionEventListener.class) {
                if (connectionEvent == null) {
                    connectionEvent = new ConnectionEvent(this);
                }
                ConnectionEventListener listener = ((ConnectionEventListener) listeners[i + 1]);
                switch (type) {
                    case CONNECT:
                        listener.connect(connectionEvent);
                        break;
                    case DISCONNECT:
                        listener.disconnect(connectionEvent);
                        break;
                }
            }
        }
    }

    @Override
    public String toString() {
        return delegate.toString();
    }

    public void remove() {
        try {
            ConnectionManager.getDefault().removeConnection(delegate);
        } catch (DatabaseException ex) {
            Exceptions.printStackTrace(ex);
        }
    }
}
